/*
 * XMLHelper.java
 *
 * Created on March 10, 2005, 9:32 PM
 */
package xml;


import dom.Writer;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 *
 * @author Keith
 */
public final class XMLHelper {

  final static private Writer writer = new Writer();
  final static private DocumentBuilderFactory dfactory =
    DocumentBuilderFactory.newInstance();
  final static private TransformerFactory tFactory =
    TransformerFactory.newInstance();
  final static private String lineSep = System.getProperty( "line.separator" );
  static private DocumentBuilder dBuilder;
  


  static {
    dfactory.setNamespaceAware( true );
//    dfactory.setCoalescing( true );

    try {
      dBuilder = dfactory.newDocumentBuilder();

      writer.setOutput( System.out, null );
    } catch ( ParserConfigurationException ex ) {
      ex.printStackTrace();
    } catch ( UnsupportedEncodingException ex ) {
      ex.printStackTrace();
    }
  }
  ;


  /** Creates a new instance of XMLHelper */
  private XMLHelper() {
  }


  static public DocumentBuilder getDocumentBuilder() {
    return dBuilder;
  }


  static public Document extractDOMNode( final NodeList gList ) {
    Document doc = null;

    if ( gList.getLength() > 0 ) {
      final NodeList Children = gList.item( 0 ).getChildNodes();

      for ( int i = 0; i < Children.getLength(); i++ ) {
        final Node child = Children.item( i );

        if ( child.getNodeType() == child.ELEMENT_NODE ) {
          doc = dBuilder.newDocument();
          doc.appendChild( doc.importNode( child, true ) );
          break;
        }
      }
    }

    return doc;
  }


  static public Document extractDOMDocument( final Element dom, final String tagName ) {
    final NodeList uList = dom.getElementsByTagName( tagName );
    Document doc = null;

    if ( uList.getLength() > 0 ) {
      doc = XMLHelper.extractDOMNode( uList );

//      XMLHelper.dump( doc );
    }

    return doc;
  }


  static public Collection<String> extractDOMCollection( final Element dom, final String tagName ) {
    final Collection<String> coll = new ArrayList<String>();

    final NodeList list = dom.getElementsByTagName( tagName );
    if ( list != null ) {

      for ( int i = 0, len = list.getLength(); i < len; i++ ) {
        final Node item = list.item( i );

        coll.add( XMLHelper.getNodeValue( item.getChildNodes() ) );
//        System.out.println( XMLHelper.getNodeValue( a.getChildNodes() ) );
      }
    }
    return coll;
  }


  public static String getNodeValue( final Node node ) {
    final StringBuffer sbuf = new StringBuffer();

    if ( node.hasChildNodes() ) {
      sbuf.append( getNodeValue( node.getChildNodes() ) );
    } else {
      sbuf.append( node.getNodeValue() );
    }

    return sbuf.toString();
  }


  public static String getNodeValue( final NodeList node ) {
    final StringBuffer sbuf = new StringBuffer();
    Node item;

    for ( int i = 0, len = ( node == null ? 0 : node.getLength() ); i < len; i++ ) {
      item = node.item( i );
      if ( item.hasChildNodes() ) {
        sbuf.append( getNodeValue( item.getChildNodes() ) );
      } else {
        sbuf.append( item.getNodeValue() );
      }
    }
    return sbuf.toString();
  }


  public static String getNodeValue( final Element dom, final String tagName ) {
    return getNodeValue( dom.getElementsByTagName( tagName ) );
  }


  static public void dump( final File file, final Node node ) throws IOException {
    final Writer writer = new Writer();
//    final java.io.Writer fileWriter = new FileWriter( file );
//    writer.setOutput( fileWriter );
    final OutputStream fileOs = new BufferedOutputStream( new FileOutputStream(
            file));
    writer.setOutput( fileOs, null );

    if ( node != null ) {
      writer.write( node );
    }
//    fileWriter.close();
    fileOs.close();
  }


  static public void dump( final Node node ) {
    if ( node != null ) {
      System.out.println( "<!-- Document Start -->" );
      writer.write( node );
      System.out.println();
      System.out.println( "<!-- Document End -->" );
      System.out.println();
    }
  }


  static public String asString( final Node node ) {
    final Writer writer = new Writer();
    final CharArrayWriter caw = new CharArrayWriter();

    writer.setOutput( caw );

    if ( node != null ) {
      caw.append( "<!-- Document Start -->" );
      caw.append( lineSep );
      writer.write( node );
      caw.append( lineSep );
      caw.append( "<!-- Document End -->" );
      caw.append( lineSep );
    }

    return caw.toString();
  }


  public static Document parse( final InputStream inStream ) throws SAXException,
                                                                    IOException {
    return dBuilder.parse( inStream );
  }


  public static Document parse( final File file ) throws FileNotFoundException,
                                                         SAXException,
                                                         IOException {
    Document doc = null;
    InputStream inStream = null;
    try {
      inStream = new BufferedInputStream( new FileInputStream( file ) );

      doc = XMLHelper.parse( inStream );
    } finally {
      if ( inStream != null ) {
        try {
          inStream.close();
        } catch ( IOException e ) {
        }
      }
    }

    return doc;
  }


  public static Transformer getTransformer( final Source src ) throws 
    TransformerConfigurationException {
    return tFactory.newTransformer( src );
  }


  public static Transformer getTransformer( final Document xslDoc ) throws 
    TransformerConfigurationException {
    return getTransformer( new DOMSource( xslDoc ) );
  }
}
